package com.hksj.base.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hksj.base.entity.Properties;
import com.hksj.base.mapper.DefaultDeviceMapper;
import com.hksj.base.query.*;
import com.hksj.base.vo.*;
import com.hksj.cbm.entity.SpaceModel;
import com.hksj.cbm.service.SpaceModelService;
import com.hksj.common.core.common.PropertyCodeUnitEnum;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.common.core.enums.DeviceState;
import com.hksj.common.core.exception.ApplicationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class DefaultDeviceService {
    @Autowired
    private DefaultDeviceMapper defaultDeviceMapper;
    @Autowired
    private SpaceModelService spaceModelService;
    @Value("${hk.td-engine.db-name:jetlinks_clean_room}")
    private String tdEngineDbName;

    public Page<DeviceStatusVO> pageDevice(BaseDeviceQuery query) {
        Page<DeviceStatusVO> page = new Page<>(query.getPageNum(),query.getPageSize());
        List<String> deviceIdList = defaultDeviceMapper.pageDeviceId(query,query.getDisAblePage() ? null : page);
        if (!ObjectUtils.isEmpty(deviceIdList)){
            query.setDeviceIdList(deviceIdList);
            List<DeviceStatusVO> list =  defaultDeviceMapper.pageDevice(query);
            wrapAddr(list);
            for (DeviceStatusVO deviceStatusVO : list) {
                if (!Objects.equals(DeviceState.online.getValue(),deviceStatusVO.getState())){
                    if (!ObjectUtils.isEmpty(deviceStatusVO.getPropertyVOList())){
                        for (PropertyVO propertyVO : deviceStatusVO.getPropertyVOList()) {
                            propertyVO.setValue(null);
                            propertyVO.setNumberValue(null);
                            propertyVO.setAlarmStatus(null);
                        }
                    }
                }
            }

            if (Objects.equals(query.getSpecialityCode(), SpecialityModelCodeEnum.air_quality.getCode())){
                // 设置属性名称
                list.stream()
                        .filter(deviceStatusVO -> !ObjectUtils.isEmpty(deviceStatusVO.getPropertyVOList()))
                        .flatMap(deviceStatusVO -> deviceStatusVO.getPropertyVOList().stream())
                        .forEach(propertyVO ->
                                propertyVO.setPropertyName(PropertyCodeUnitEnum.getName(propertyVO.getProperty()))
                        );
            }
            page.setRecords(list);
        }else{
            page.setRecords(new ArrayList<>());
        }
        return page;
    }

    public Page<DeviceStatusVO> pageAlarmDevice(BaseAlarmDeviceQuery query) {
        Page<DeviceStatusVO> page = new Page<>(query.getPageNum(),query.getPageSize());
        query.setState(DeviceState.online.getValue());
        List<String> deviceIdList = defaultDeviceMapper.pageAlarmDeviceId(query,query.getDisAblePage() ? null : page);
        if (!ObjectUtils.isEmpty(deviceIdList)){
            query.setDeviceIdList(deviceIdList);
            List<DeviceStatusVO> list =  defaultDeviceMapper.pageDevice(query);
            wrapAddr(list);
            page.setRecords(list);
        }else{
            page.setRecords(new ArrayList<>());
        }
        return page;
    }

    public DeviceVO getDeviceInfo(String deviceId){
        DeviceVO deviceVO = defaultDeviceMapper.getDeviceInfo(deviceId);
        return deviceVO;
    }

    public Page<Properties> pageRecord(BaseRecordQuery query) {
        Page<Properties> page = new Page<>(query.getPageNum(), query.getPageSize());
        setQueryTime(query);
        DeviceVO deviceVO = getDeviceInfo(query.getDeviceId());
        query.setTableName(getTableName(deviceVO.getProductId()));

        //设置产品分类
        query.setProductClassifiedCode(deviceVO.getProductClassifiedCode());

        List<Properties> list = defaultDeviceMapper.pageRecord(query);

        if (!ObjectUtils.isEmpty(list)){
            for (Properties properties : list) {
                if (Objects.equals(properties.getProperty(),SpecialityModelCodeEnum.Jfaq_lous.getCode())){
                    properties.setValue(Objects.equals("1",properties.getValue()) ? "是" : "否");
                }
            }
        }

        Long count = defaultDeviceMapper.count(query);
        page.setTotal(count);
        page.setRecords(list);
        return page;
    }

    public List<ChartVO> listChartData(ChartQuery chartQuery){
        List<ChartVO> res = new ArrayList<>();
        BaseRecordQuery query = new BaseRecordQuery();
        query.setDeviceId(chartQuery.getDeviceId());
        query.setType(chartQuery.getType());
        setQueryTime(query);
        DeviceVO deviceVO = getDeviceInfo(chartQuery.getDeviceId());
        query.setTableName(getTableName(deviceVO.getProductId()));
        List<Properties> list = defaultDeviceMapper.listRecord(query);
        if (!ObjectUtils.isEmpty(list)){
            Map<String, List<Properties>> propertiesMap = list.stream().collect(Collectors.groupingBy(Properties::getProperty));
            for (String key : propertiesMap.keySet()) {
                res.add(new ChartVO(key,propertiesMap.get(key).get(0).getUnit(),propertiesMap.get(key).get(0).getPropertyName(),propertiesMap.get(key)));
            }
        }
        if (!CollectionUtils.isEmpty(res)){
            res.forEach(item -> {
                if (!ObjectUtils.isEmpty(PropertyCodeUnitEnum.getVal(item.getProperty()))){
                    item.setUnit(PropertyCodeUnitEnum.getVal(item.getProperty()));
                }
                if (!ObjectUtils.isEmpty(PropertyCodeUnitEnum.getName(item.getProperty()))){
                    item.setPropertyName(PropertyCodeUnitEnum.getName(item.getProperty()));
                }
            });
        }
        return res;
    }

    private void setQueryTime(BaseRecordQuery query){
        Date now = new Date();
        if (query.getType() == 1){
            query.setStartTime(DateUtil.offsetHour(now,-24).getTime());
            query.setEndTime(now.getTime());
        }else if(query.getType() == 2){
            query.setStartTime(DateUtil.offsetDay(now,-7).getTime());
            query.setEndTime(now.getTime());
        }else if(query.getType() == 3){
            query.setStartTime(DateUtil.beginOfDay(DateUtil.offsetDay(now,-29)).getTime());
            query.setEndTime(now.getTime());
        }else if(query.getType() == 4){
            query.setStartTime(DateUtil.beginOfDay(DateUtil.offsetMonth(now,-11)).getTime());
            query.setEndTime(now.getTime());
        }else if (query.getType() == 5){
            //最近半年
            query.setStartTime(DateUtil.offsetMonth(now, -6).getTime());
            query.setEndTime(now.getTime());
        } else{
            throw new ApplicationException("type 字段传值不正确");
        }
    }

    public DeviceOverviewVO getDeviceOverview(DeviceOverviewQuery query) {
        DeviceOverviewVO res = defaultDeviceMapper.getDeviceOverview(query);
        return res;
    }

    public List<ProductDeviceOverviewVO> listProductDeviceOverview(DeviceOverviewQuery query) {
        return defaultDeviceMapper.listProductDeviceOverview(query);
    }

    public String getTableName(String productId){
        return tdEngineDbName + ".properties_" + productId;
    }

    /**
     * 赋值位置信息
     * @param list
     */
    public void wrapAddr(List<? extends LocationVO> list){
        if (!ObjectUtils.isEmpty(list)){
            Set<Long> pathIdSet = new HashSet<>();
            for (LocationVO locationVO : list) {
                if (!ObjectUtils.isEmpty(locationVO.getPaths())) {
                    String[] pathArr = locationVO.getPaths().split(",");
                    pathIdSet.addAll(Arrays.stream(pathArr).map(pathStr -> Long.parseLong(pathStr)).collect(Collectors.toSet()));
                }
            }

            if (!ObjectUtils.isEmpty(pathIdSet)){
                List<SpaceModel> spaceList = spaceModelService.listByIds(pathIdSet);
                Map<Long, SpaceModel> spaceModelMap = spaceList.stream().collect(Collectors.toMap(SpaceModel::getId, Function.identity()));
                for (LocationVO locationVO : list) {
                    if (!ObjectUtils.isEmpty(locationVO.getPaths())){
                        String[] pathArr = locationVO.getPaths().split(",");
                        for (String pathStr : pathArr) {
                            SpaceModel spaceModel = spaceModelMap.get(Long.parseLong(pathStr));
                            if (!ObjectUtils.isEmpty(spaceModel)) {
                                switch (spaceModel.getLevel()) {
                                    case 1:
                                        locationVO.setBuildingId(spaceModel.getId());
                                        locationVO.setBuildingName(spaceModel.getModelName());
                                        break;
                                    case 2:
                                        locationVO.setFloorId(spaceModel.getId());
                                        locationVO.setFloorName(spaceModel.getModelName());
                                        break;
                                    case 3:
                                        locationVO.setRoomId(spaceModel.getId());
                                        locationVO.setRoomName(spaceModel.getModelName());
                                        break;
                                    case 4:
                                        locationVO.setAddressId(spaceModel.getId());
                                        locationVO.setAddress(spaceModel.getModelName());
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public String getAddr(AlarmRecordVO alarmRecordVO){
        StringBuffer addrSb = new StringBuffer();
        if (!ObjectUtils.isEmpty(alarmRecordVO.getBuildingName())){
            addrSb.append(alarmRecordVO.getBuildingName());
        }
        if (!ObjectUtils.isEmpty(alarmRecordVO.getFloorName())){
            if (addrSb.length() > 0){
                addrSb.append("->");
            }
            addrSb.append(alarmRecordVO.getFloorName());
        }
        if (!ObjectUtils.isEmpty(alarmRecordVO.getRoomName())){
            if (addrSb.length() > 0){
                addrSb.append("->");
            }
            addrSb.append(alarmRecordVO.getRoomName());
        }
        if (!ObjectUtils.isEmpty(alarmRecordVO.getAddress())){
            if (addrSb.length() > 0){
                addrSb.append("->");
            }
            addrSb.append(alarmRecordVO.getAddress());
        }
        return addrSb.toString();
    }

    public DeviceStatusVO getDeviceCurrentProperty(String deviceId) {
        BaseDeviceQuery query = new BaseDeviceQuery();
        query.setDeviceIdList(Arrays.asList(deviceId));
        List<DeviceStatusVO> list =  defaultDeviceMapper.pageDevice(query);
        if (!ObjectUtils.isEmpty(list)){
            return list.get(0);
        }
        return null;
    }

    public DefaultDeviceMapper getDefaultDeviceMapper() {
        return defaultDeviceMapper;
    }
}
